#include"RecDown.h"
//!E::=T{[+-]T}*
//!P::=(E) | N
//!T::=P{[*/]p}*
//!N::=['0'-'9']+
//!G0 ::= E with init and geting answer.

char GL_str[1000] = "";
int GL_pos = 0;
node_t* getG0()
{
    scanf("%s", GL_str);
    GL_pos = 0;
    GL_str[strlen(GL_str)] = 0;
    node_t* val = getE();
    if(GL_str[GL_pos] == '=')
       {GL_pos++;val = nodeNew(MOV, "", val, getE());}
    if(GL_str[GL_pos] == 0)
        return val;
    else
        printf("Syntax Error: Unknown character <%c>", GL_str[GL_pos]);
    return NULL;
}
node_t* getE()
{
    node_t* val = getT();
    while(GL_str[GL_pos] == '+' || GL_str[GL_pos] == '-')
    {
        GL_pos++;
        if (GL_str[GL_pos-1] == '+')
            val = nodeNew(PLUS, "", val, getT());
        if (GL_str[GL_pos-1] == '-')
            val = nodeNew(SUB, "", val, getT());
    }
    return val;
}
node_t* getT()
{
    node_t* val = getP();
    while(GL_str[GL_pos] == '*' || GL_str[GL_pos] == '/')
    {
        GL_pos++;
        if (GL_str[GL_pos-1] == '*')
            val = nodeNew(MUL, "", val, getP());
        if (GL_str[GL_pos-1] == '/')
            val = nodeNew(DIV, "", val, getP());
    }
    return val;
}

node_t* getP()
{
    node_t* val;
    if(GL_str[GL_pos] == '(')
    {
        GL_pos++;
        val = getE();
        if(GL_str[GL_pos] == ')')
            GL_pos++;
    }

    else if(isdigit(GL_str[GL_pos]))
        val = getN();

    else if(isalpha(GL_str[GL_pos]) || GL_str[GL_pos] == '_')
        val = getV();

    if (GL_str[GL_pos] == '^')
    {
        GL_pos++;
        val = nodeNew(DEGREE, "^", val, getN());
    }
    return val;
}
node_t* getN()
{
    double value = 0;
    while(isdigit(GL_str[GL_pos]))
    {
        value = value*10 + GL_str[GL_pos] - '0';
        GL_pos++;
    }
    return nodeNew(value, NULL, NULL);
}
node_t* getV()
{
    char name[20];
    int i = 0;
    while(isalpha(GL_str[GL_pos]) || GL_str[GL_pos] == '_')
    {
        name[i++] = GL_str[GL_pos];
        GL_pos++;
    }
    name[i] = 0;

    int fnumber = isFunction(name);
    if(fnumber > 0 && GL_str[GL_pos] == '(')
    {
        GL_pos++;
        node_t* n = NULL;
        n = nodeNew(fnumber, name, NULL, getE());
        if(GL_str[GL_pos] == ')')
        {
            GL_pos++;
            return n;
        }
        else
            return NULL;
    }
    return nodeNew(VARIABLE, name, NULL, NULL);
}

int isFunction(char name[])
{
    if  (!strcmp(name, "log"))
        return LOG;
    else if(!strcmp(name, "sin"))
        return SIN;
    else if(!strcmp(name, "cos"))
        return COS;
    else if(!strcmp(name, "EXP"))
        return EXP;
    else if(!strcmp(name, "^"))
        return DEGREE;
    else
        return 0;
}
